package gateway

import (
	"errors"
	"fmt"
)

var _ IDeviceGatewayManager = (*deviceGatewayManager)(nil)

var (
	DeviceGatewayManager = new(deviceGatewayManager)
	// Providers 设备网关服务提供者
	Providers = make(map[string]IDeviceGatewayProvider)
	// Store 启动状态的设备网关
	Store = make(map[int64]IDeviceGateway)
)

type (
	IDeviceGatewayManager interface {
		GetGateway(id int64, deviceGatewayConfig *DeviceGatewayProperties) (IDeviceGateway, error)
		Shutdown(id int64)
		GetProviders() []IDeviceGatewayProvider
	}

	deviceGatewayManager struct {
	}
)

func (d *deviceGatewayManager) GetGateway(id int64, deviceGatewayConfig *DeviceGatewayProperties) (IDeviceGateway, error) {
	if _, ok := Store[id]; ok {
		return Store[id], nil
	}

	// 创建网关
	gateway, err := doGetGateway(id, deviceGatewayConfig)
	if err != nil {
		return nil, err
	}
	return gateway, nil
}

func (d *deviceGatewayManager) Shutdown(gatewayId int64) {
	gateway := Store[gatewayId]
	gateway.Shutdown()
	delete(Store, gatewayId)
}

func (d *deviceGatewayManager) GetProviders() []IDeviceGatewayProvider {
	var iDeviceGatewayProvider []IDeviceGatewayProvider
	for _, v := range Providers {
		iDeviceGatewayProvider = append(iDeviceGatewayProvider, v)
	}
	return iDeviceGatewayProvider
}

func doGetGateway(id int64, deviceGatewayConfig *DeviceGatewayProperties) (IDeviceGateway, error) {
	if _, ok := Store[id]; ok {
		return Store[id], nil
	}

	if deviceGatewayConfig == nil {
		return nil, errors.New(fmt.Sprintf("网关配置ID：%d，不存在, Err: %+v", id, nil))
	}

	// 获取网关提供者
	provider := Providers[deviceGatewayConfig.Provider]
	if provider == nil {
		return nil, errors.New(fmt.Sprintf("网关配置ID：%d，不支持的网络服务, Err: %+v", id, nil))
	}

	// 创建设备网关
	gateway, _ := provider.CreateDeviceGateway(deviceGatewayConfig)

	if _, ok := Store[id]; ok {
		gateway.Shutdown()
		return Store[id], nil
	}
	Store[id] = gateway
	return gateway, nil
}
